/* 
    动机：
        1. 使用类的好处：客户端可以修改对象的核心数据，通过计算得出的派生数据会自动和核心数据保持一致；
        2. 一组函数可以组合成类。

    做法：
        1. 运用【封装记录】对多个函数公用的数据记录加以封装；
        2. 对于使用该记录结构的每个函数，运用【搬移函数】将其移入新类；
        3. 用以处理该数据记录的逻辑可以用【提炼函数】提炼出来，并移入新类。
*/

const reading = { customer: "ivan", quantity: 10, month: 5, year: 2017 };

// client 1
const aReading = acquireReading();
const baseCharge = baseRate(aReading.month, aReading.year) * aReading.quantity;

// client 2
const aReading2 = acquireReading();
const baseCharge2 = baseRate(aReading.month, aReading.year) * aReading.quantity;
const taxableCharge = Math.max(0, base - taxThreshold(aReading.year));

// client 3
const aReading3 = acquireReading();
const basicChargeAmount = calculateBaseCharge(aReading);

function calculateBaseCharge() {
    return baseRate(aReading.month, aReading.year) * aReading.quantity;
}

/**************************************************************************** */
/* 
    -- 当 calculateBaseCharge() 位于一个文件中时，读者不一定能想得到来这里寻找它。
    -- 所以可以对代码多做些修改，让该函数与其处理的数据在空间上有更紧密的联系。
    -- 为此目的，可以把数据本身变成一个类。
*/
class Reading {
    constructor(customer, quantity, month, year) {
        this._customer = customer;
        this._quantity = quantity;
        this._month = month;
        this._year = year;
    }

    getCustomer() {
        return this._customer;
    }
    getQuantity() {
        return this._quantity;
    }
    getMonth() {
        return this._month;
    }
    getYear() {
        return this._year;
    }

    baseCharge() {
        return baseRate(this._month, this._year) * this._quantity;
    }

    taxableCharge(aReading){
     return  Math.max(0, aReading.baseCharge - taxThreshold(aReading.year));   
    }
}

// client 4
const rawReading = acquireReading();
const aReading4 = new Reading(rawReading);
const baseCharge4 = aReading4.baseCharge();
const taxableCharge4 = aReading4.taxableCharge(aReading4);

